﻿using FreeScheduler;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Domain.LoginLog;
using ZhonTai.Admin.Services;
using ZhonTai.Admin.Tools.Cache;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
using ZhonTai.Industry.Contracts.Core.Enums;
using ZhonTai.Industry.Core.Consts;
using ZhonTai.Industry.Domain.GenericBinding;
using ZhonTai.Industry.Domain.ProductModel;
using ZhonTai.Industry.Domain.WorkOrder;
using ZhonTai.Industry.Domain.WorkParamRecord;
using ZhonTai.Industry.Domain.WorkStation;
using ZhonTai.Industry.Domain.WorkStationRecord;
using ZhonTai.Industry.Services.ExternalService.Dto.Input;
using ZhonTai.Industry.Services.ExternalService.Dto.Output;
using ZhonTai.Industry.Services.WorkStationRecord;
using ZhonTai.Industry.Services.WorkStationRecord.Dto.Output;

namespace ZhonTai.Industry.Services.ExternalService
{
    /// <summary>
    /// 供外部无权限调用服务
    /// </summary>
    [DynamicApi(Area = IndustryConsts.AreaName)]
    [AllowAnonymous]
    public class ExternalService : BaseService, IExternalService, IDynamicApi
    {
        private readonly IWorkParamRecordRepository _workParamRecordRepository;
        private readonly IWorkStationRecordRepository _workStationRecordRepository;
        private readonly IWorkStationRepository _workStationRepository;
        private readonly IGenericBindingRepository _genericBindingRepository;
        private readonly IWorkStationRecordService _workStationRecordService;
        private readonly IWorkOrderRepository _workOrderRepository;
        private readonly IProductModelRepository _productModelRepository;
        private readonly ILoginLogRepository _loginLogRepository;

        public ExternalService(
            IWorkParamRecordRepository workParamRecordRepository,
            IWorkStationRepository workStationRepository,
            IWorkStationRecordRepository workStationRecordRepository,
            IGenericBindingRepository genericBindingRepository,
            IWorkOrderRepository workOrderRepository,
            IWorkStationRecordService workStationRecordService,
            IProductModelRepository productModelRepository,
            ILoginLogRepository loginLogRepository)
        {
            _workParamRecordRepository = workParamRecordRepository;
            _workStationRecordRepository = workStationRecordRepository;
            _workStationRepository = workStationRepository;
            _genericBindingRepository = genericBindingRepository;
            _workOrderRepository = workOrderRepository;
            _workStationRecordService = workStationRecordService;
            _productModelRepository = productModelRepository;
            _loginLogRepository = loginLogRepository;
        }

        #region 数据接收

        /// <summary>
        /// 接收外来加工数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost]
        public async Task ReceiveWorkParamAsync(IEnumerable<ReceiveWorkParamAddInput> input)
        {
            if (!input.Any())
            {
                throw ResultOutput.Exception("传递数据为空！");
            }
            //订单ID
            long? orderId = await Cache.GetAsync<long?>(CacheKey.StationId);
            //产品型号ID
            long? productId = await Cache.GetAsync<long?>(CacheKey.ProductId);
            var paramList = input.Select(x =>
            {
                var workstaionEntity = _workStationRepository.Select.Where(z => z.StationCode == x.StationCode).ToOne();
                var paramEntity = new WorkParamRecordEntity()
                {
                    StationId = workstaionEntity != null ? workstaionEntity.Id : 676035343577093,
                    OrderId = orderId,
                    ProductModelId = productId,
                    ProductCode = x.ProductId,
                    ParameterName = x.ProcessName,
                    ParameterValue = x.ProcessValue,
                    Unit = x.UnitName,
                    Status = x.WorkResult,
                    CreatedTime = x.CreationTime,
                };
                return paramEntity;
            }).ToList();
            DateTime minTime = (DateTime)paramList.OrderByDescending(x => x.CreatedTime).First().CreatedTime;
            var stationRecordEntity = new WorkStationRecordEntity
            {
                ProductCode = paramList.First().ProductCode,
                StationId = paramList.First().StationId,
                OrderId = orderId,
                ProductModelId = productId,
                ShiftId = 1,
                StartTime = minTime,
                EndTime = DateTime.Now,
                CycleTime = (DateTime.Now - minTime).TotalSeconds,
                Result = paramList.First().Status
            };
            await _workStationRecordRepository.InsertAsync(stationRecordEntity);
            await _workParamRecordRepository.InsertAsync(paramList);
        }

        /// <summary>
        /// 接收清洗篮绑定
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task AddLotBasketCodeAsync(LotBasketCodeAddInput input)
        {
            var genericBindingEntity = await _genericBindingRepository.Select.Where(x => x.CodeA == input.BasketCode).ToOneAsync();
            if (genericBindingEntity == null)
            {
                genericBindingEntity = new GenericBindingEntity()
                {
                    CodeA = input.BasketCode,
                    CodeB = input.LotCode,
                    BindingType = "BatchBind"
                };
            }
            else
            {
                genericBindingEntity.CodeB = input.LotCode;
                genericBindingEntity.Count = 0;
                genericBindingEntity.BindingType = "BatchBind";
                genericBindingEntity.Label = null;
                genericBindingEntity.Status = StatusEnum.Close;
            }
            await _genericBindingRepository.InsertOrUpdateAsync(genericBindingEntity);
        }

        #endregion 数据接收

        #region 数据发送

        /// <summary>
        /// 发送清洗篮批次绑定数据
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IEnumerable<LotBasketCodeListOutput>> SendLotBasketCodeListAsync()
        {
            return await _genericBindingRepository.Select
                  .Where(x => x.Status == StatusEnum.Close)
                  .OrderByDescending(x => x.CreatedTime)
                  .Take(20)
                  .ToListAsync(t => new LotBasketCodeListOutput() { BasketCode = t.CodeA, LotCode = t.CodeB, CreatedTime = t.ModifiedTime });
        }

        /// <summary>
        /// 发送今日加工详情
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ProcessDataResultOutput> SendProductLineOverViewAsync()
        {
            return await _workStationRecordService.ComputeProcessDataAsync();
        }

        /// <summary>
        /// 发送产品下线记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IEnumerable<ProductOfflineOutput>> SendProductOfflineRecordAsync()
        {
            var offlinestations = await _workStationRepository.Select.Where(w => w.StationType.Equals("Offline")).ToListAsync(t => t.Id);
            return await _workStationRecordRepository.Select
                .Where(r => offlinestations.Contains(r.StationId))
                .OrderByDescending(x => x.CreatedTime)
                .Take(10)
                .ToListAsync(x => new ProductOfflineOutput() { ProductCode = x.ProductCode, Result = x.Result, RecordTime = x.CreatedTime });
        }

        /// <summary>
        /// 发送生产展示信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ProductionShowOutput> SendProductionShowAsync()
        {
            ProductionShowOutput productionShow = new ProductionShowOutput();
            var orderEntity = await _workOrderRepository.Select.Where(x => x.State == 1).ToOneAsync();
            if (orderEntity != null)
            {
                productionShow.OrderCode = orderEntity.OrderCode;
            }
            long? productId = await Cache.GetAsync<long?>(CacheKey.ProductId);
            var productModelEntity = await _productModelRepository.Select.Where(x => x.Id == productId).ToOneAsync();
            if (productModelEntity != null)
            {
                productionShow.ProductModel = productModelEntity.ProductName;
            }
            var loginLogEntity = await _loginLogRepository.Select.OrderByDescending(x => x.CreatedTime).ToOneAsync();
            if (loginLogEntity != null)
            {
                productionShow.TotalTime = (int)(DateTime.Now - loginLogEntity.CreatedTime).Value.TotalMinutes;
            }
            return productionShow;
        }

        #endregion 数据发送
    }
}